package megalopolis.server;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import megalopolis.model.GameObject;
import megalopolis.model.Man;
import megalopolis.net.Request;
import megalopolis.net.requests.LoginRequest;
import megalopolis.net.requests.MoveRequest;
import megalopolis.net.responses.LoginResponse;
import megalopolis.net.responses.MapUpdatedResponse;

/**
 * User: Kirill
 * Date: 18.03.2008
 */
public class RequestHandler {

	private NetworkHandler networkHandler;

	private WorldHelper worldHelper;

	public RequestHandler(NetworkHandler networkHandler, World world) {
		this.networkHandler = networkHandler;
		this.worldHelper = new WorldHelper(world);
	}

	public void handleRequests(Map<Player, List<Request>> requests) {
		for (Player player : requests.keySet()) {
			List<Request> playerRequests = requests.get(player);

			// filter requests // todo: optimize it
			Iterator<Request> requestIt = playerRequests.iterator();
			boolean alreadyMoved = false;
			while (requestIt.hasNext()) {
				Request request = requestIt.next();
				if (request instanceof MoveRequest) {
					if (alreadyMoved) {
						requestIt.remove();
					} else {
						alreadyMoved = true;

						handleRequest(player, request);
					}
				} else {
					handleRequest(player, request);
				}
			}
		}
	}

	private void handleRequest(Player player, Request request) {
		if (request instanceof MoveRequest) {
			handleMove(player, (MoveRequest) request);
		} else if (request instanceof LoginRequest) {
			handleLoginRequest(player, (LoginRequest) request);
		}
	}

	private void handleLoginRequest(Player player, LoginRequest loginRequest) {
		String login = loginRequest.getLogin();
		String password = loginRequest.getPassword();

		boolean logined = false;
		if ("".equals(login) && "".equals(password)) {
			logined = true;
		}

		networkHandler.sendResponse(player, new LoginResponse(logined));

		if (logined) {
			// create man and assign it to player
			Man man = new Man();
			worldHelper.addMan(man);
			player.setMan(man);

			// update objects in the area
			updatePlayerObjects(player);
		}
	}

	private void updatePlayerObjects(Player player) {
		Set<GameObject> gameObjects = worldHelper.getGameObjects(player.getMan());
		networkHandler.sendResponse(player, new MapUpdatedResponse(player.getMan(), gameObjects));
	}

	private void handleMove(Player player, MoveRequest moveRequest) {
		MoveRequest.Movement movement = moveRequest.getMovement();

		// now we now that we are a man, but in future we must check if we sit in the car or something like that
		Man man = player.getMan();
		switch (movement) {
			case LEFT:
				man.x -= 1;
				break;
			case RIGHT:
				man.x += 1;
				break;
			case FORWARD:
				man.y += 1;
				break;
			case BACKWARD:
				man.y -= 1;
				break;
		}

		Set<GameObject> gameObjects = worldHelper.getGameObjects(player.getMan());
		networkHandler.sendResponse(player, new MapUpdatedResponse(player.getMan(), gameObjects));
	}

	public void startStep() {
	}

	public void applyStep() {
	}

}
